Repository navigation
Select text inside tables (#33) - #39
Merged
Merged
Conversation
…eight TableTextBuilder builds one attributed string per table (one paragraph per cell, reading order, NSTextTable blocks); TableTextView (a SelfSizingTextView) draws it; BlockHeightMeasurer measures the same string, so table rows are .exact. TableBlockView removed (print keeps PrintableTableView). Search keeps 1.12 behaviour through a bridge until TS-T3. Not shippable alone: tables are still atomic in the selection until TS-T2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
…text Table matches are counted with the same matcher over the same characters the table view shows (the measurer's TableText string, or a plain string from the same builder helpers), so count == highlights, in reading order; markup and link URLs are no longer counted. Highlight through applyNSSearchHighlight (moved to DocumentSearch.swift for headless tests). The 1.12 bridge and the dead SwiftUI highlight path are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
… no rebuild per pass - FullWidthTextTable: whole-point columns that sum to the full width (the remainder 1 pt each to the first columns), so the header band and rules reach the outline (NSTextTable floored every column: up to n-1 pt short). - TableText.Source carries theme name, dark/light and document fonts; matches(theme:fontScale:) rejects an instance built for another look. - The representable builds or adopts a TableText only when its source changes; the background colour is compared by value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
Tables are no longer atomic in the document selection: the controller asks the row's text view for the character under the pointer (cell-confined in tables), multi-click selects a word or the cell, and copy builds the covered text of one cell, or TSV of the covered cells (partial first/last cell), or the 1.12 TSV for a whole table. Per-row selection rules moved to a pure SelectionRows.swift so they are unit-tested; Source Edit hint lands on the table's line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
searchMatchRanges returned ranges in the lowercased copy's coordinates; "İ" lowercases to two UTF-16 units, so every later highlight of a row (a whole table) shifted by one. When the lowercased length differs, search the original string with .caseInsensitive; otherwise unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
- multi-click on text rows is exactly the pre-v1.13 glyph rule; the cell rule compares against the glyph's composed character range (emoji, ZWJ) - Source Edit hint inside one table band searches that band's source line only (repeated values in a column no longer land on another row) - a single-cell copy drops the column's alignment as well as the text block Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
…selection A table fills a background and borders per cell, and every fill computed the rects of the WHOLE selection to cut its holes: quadratic. ⌘A ⌘C on a 200-row table took 7 s on first draw and grew the process to 3 GB (1.12: 0.35 s, 110 MB). `selectionRects(in:limitedTo:)` takes the fill's character range and keeps the whole covered range as the selected range, so line ends extend exactly as before; the limited rects add up to the whole selection's (test). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
- hit-test: a table clamps the point into its view and asks the cell hook in every direction (TS-D6); text rows keep their edges - whole-table copy reads the built cells (one source of truth, no second renderInline pass), 1.12 parity pinned on rich fixtures - text rows are counted with searchMatchRanges, so count == highlights - drop the unused 4-arg TableText.matches and TableTextLayout.bandRange; stale comments (tables are .exact, on-screen cells are AppKit) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhzVb6aPQs2FF1bHdkcYys
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CI gate for the local
--no-ffmerge offeature/table-select;mainwill be fast-forwarded to this branch once CI is green.Tables were atomic in the document selection (selected whole, copied as TSV). Now a word, a whole cell (triple-click) or any range of cells can be selected (asked for on #33).
NSTextViewper table with a TextKit 1NSTextTablestring (TableTextBuilder, one paragraph per cell, reading order); the same string is measured off-main, so table rows are.exact. Look unchanged from 1.12 (verified side by side); columns span the full width (FullWidthTextTable).Local: 751 tests, Release + Release-APPSTORE; reviews after each of the three tasks plus a holistic one; E2E on sandboxed and unsandboxed
.protobuilds (drag in a cell, across cells, header to row, paragraph to table, Shift-click, double/triple-click, ⌘A ⌘C, autoscroll through 200 rows, resize keeping the selection, edge slips, links in cells, Source Edit hint with repeated values, search stepping, zoom, light/dark).